/**
 * 
 * @brief  net_protocol.c
 * @param  None
 * 
 * @author xhq
 * @date   2024/11/01
 * 
 */
/* include */
#include "net_protocol.h"

/* global variable */
// 发送方标识信息
IDENTITY g_net_recv_send_id;
// 原始mipi数据请求信息
ORIGNAL_MIPI_REQ g_mipi_req_info;
// dsp原始目标数据请求信息
DSP_CAL_DATA_REQ g_dsp_req_info;
// 发送原始mipi数据至上位机标志,1--开始上传,0--停止上传
uint32_t g_mipi_data_upload_flag =0;
// 记录已经接收的mipi数据的帧数
uint32_t g_recv_mipi_frame_cnt;
// 记录已经接收的半帧mipi数据的次数
uint32_t g_recv_mipi_half_frame_cnt;
// mipi数据上传后回复是否成功标识位，0--成功；1--失败
uint8_t g_mipi_upload_status =0;
uint32_t g_mipi_frame_index_rev = 0;
/* define */

/* typedef */

/* function */
/* function */
/*****************************************************************************/
/**
*
* 解析上位机针对上传的原始mipi数据信息的回复信息
*
* @param p_mipi_response ：上传mipi数据的回复数据部分
*
* @return uint32_t：0：成功，1--失败
*
* @note		None.
*
*****************************************************************************/
uint32_t anlysis_origi_mipi_res(ORIGNAL_MIPI_RES *p_mipi_response)
{
    /* 检查参数合法性 */
    if (p_mipi_response == NULL)
    {
        printf("anlysis_origi_mipi_res para error.\n");
        return -1;
    }

    uint32_t l_u32req_total_frame_num = 0;
    uint32_t l_u32res_frame_cnt = 0;
    uint8_t  l_u8recv_status = 0;

    /* 信息解析 */
    l_u32req_total_frame_num = p_mipi_response->req_total_frame_num;
    g_mipi_frame_index_rev = p_mipi_response->res_frame_cnt;
    l_u8recv_status = p_mipi_response->recv_status;
    g_mipi_upload_status = l_u8recv_status;

    /* debug */
    // if (!l_u8recv_status)
    // {
    //     printf("total %u frame mipi, %uth uploaded ok.\n", l_u32req_total_frame_num, (l_u32res_frame_cnt + 1));
    // }
    // else
    // {
    //     printf("total %u frame mipi, %uth uploaded err.\n", l_u32req_total_frame_num, (l_u32res_frame_cnt + 1));
    // }

    /* 通知mipi数据上传线程 */
    sem_post(&g_mipi_send_res_semaphore);
    
    return 0;
}

/*****************************************************************************/
/**
*
* 解析请求原始mipi数据的信息,赋值给全局变量g_mipi_req_info
*
* @param p_mipi_request ：mipi请求信息指针
*
* @return uint32_t：0：成功，1--失败
*
* @note		None.
*
*****************************************************************************/
uint32_t anlysis_origi_mipi_req(ORIGNAL_MIPI_REQ *p_mipi_request)
{
    /* 检查参数合法性 */
    if (p_mipi_request == NULL)
    {
        printf("anlysis_origi_mipi_req para error.\n");
        return -1;
    }

    /* 信息解析 */
    g_mipi_req_info.req_mipi_num = p_mipi_request->req_mipi_num;
    g_mipi_req_info.each_frame_data_len = p_mipi_request->each_frame_data_len;
    g_mipi_req_info.rf_channel = p_mipi_request->rf_channel;
    g_mipi_req_info.each_chirp_data_len = p_mipi_request->each_chirp_data_len;
    g_mipi_req_info.chirp_num = p_mipi_request->chirp_num;
    g_mipi_req_info.data_type = p_mipi_request->data_type;
    g_mipi_req_info.tx_num = p_mipi_request->tx_num;
    g_mipi_req_info.wave_braud = p_mipi_request->wave_braud;

    if (g_mipi_req_info.rf_channel == 0x00)         // 远端
    {
        g_mipi_recv_info.mipi_index[0].fram_count =0;
        g_mipi_recv_info.mipi_index[0].need_handle_fram_num = g_mipi_req_info.req_mipi_num;

        g_mipi_recv_info.mipi_index[1].fram_count =0;
        g_mipi_recv_info.mipi_index[1].need_handle_fram_num = g_mipi_req_info.req_mipi_num;
    }
    else if (g_mipi_req_info.rf_channel == 0x02)    // 近端
    {
        g_mipi_recv_info.mipi_index[2].fram_count =0;
        g_mipi_recv_info.mipi_index[2].need_handle_fram_num = g_mipi_req_info.req_mipi_num;

        g_mipi_recv_info.mipi_index[3].fram_count =0;
        g_mipi_recv_info.mipi_index[3].need_handle_fram_num = g_mipi_req_info.req_mipi_num;
    }

    printf("**frame_num:%d rf:%d data_type:%d tx_num:%d wave_braud:%d **\n",
        g_mipi_req_info.req_mipi_num,g_mipi_req_info.rf_channel,g_mipi_req_info.data_type,g_mipi_req_info.tx_num,g_mipi_req_info.wave_braud);


    switch(g_mipi_req_info.data_type){
        case 0:
        break;
        case 1://1：移相器标定 送天线序号  1/2/4/8/16/32/64/128    仅上传数据类别为2:移相器标定时有效
            
        break;
        case 2: //2：通道标定；仅上传数据类别为2:通道标定时有效
        break;
        default:
        break;
    }

    //0:远 2：近
 //   g_mipi_req_info.rf_channel = 2;

    /* 上传mipi数据标志位置1 */
    if(g_mipi_req_info.req_mipi_num > 0)
    {
        g_mipi_data_upload_flag = 0x01;
    }


    /* 保存的即将上传的mipi数据帧数清0 */
    g_recv_mipi_frame_cnt = 0;      

   /* 保存的即将上传的mipi数据半帧数清0 */
    g_recv_mipi_half_frame_cnt = 0;

    return 0;
}


/*****************************************************************************/
/**
*
* 解析请求dsp数据的信息,赋值给全局变量g_dsp_req_info
*
* @param p_dsp_request ：dsp请求信息指针
*
* @return uint32_t：0：成功，1--失败
*
* @note		None.
*
*****************************************************************************/
uint32_t anlysis_dsp_req(DSP_CAL_DATA_REQ *p_dsp_request)
{
    /* 检查参数合法性 */
    if (p_dsp_request == NULL)
    {
        printf("anlysis_dsp_req para error.\n");
        return -1;
    }

    /* 信息解析 */
    g_dsp_req_info.req_dsp_frame_num = p_dsp_request->req_dsp_frame_num;
    g_dsp_req_info.frame_type = p_dsp_request->frame_type;
    g_dsp_req_info.data_type = p_dsp_request->data_type;
    g_dsp_req_info.enable_flag = p_dsp_request->enable_flag;

    printf("req_dsp_frame_num = %u, frame_type = %u, data_type = %u, enable_flag = %u.\n", 
        g_dsp_req_info.req_dsp_frame_num, g_dsp_req_info.frame_type, g_dsp_req_info.data_type, g_dsp_req_info.enable_flag);

    return 0;
}


/*****************************************************************************/
/**
*
* net_anlysis_procotol
*
* @param l_sockaddr ：接收数据包ip地址
* @param l_u8_recv_buf：接收的数据包
* @param l_u32_data_len：接收的数据包长度
*
* @return uint32_t：0：正常，非0：错误代码
*
* @note		None.
*
*****************************************************************************/
uint32_t net_anlysis_procotol(struct sockaddr * l_sockaddr, uint8_t *l_u8_recv_buf, uint32_t l_u32_data_len)
{
    uint32_t l_u32_ret = 0;
    uint32_t l_u32_idx = 0;
    uint32_t l_u32_recv_data_len = 0;
    IDENTITY *p_id = NULL;
    uint8_t l_u8protol_ver = 0;
    uint8_t l_u8operate_type = 0;
    uint16_t l_u16operate_target = 0;
    ORIGNAL_MIPI_REQ *p_mipi_req = NULL;
    ORIGNAL_MIPI_RES *p_mipi_res = NULL;
    DSP_CAL_DATA_REQ *p_dsp_req = NULL;

    /* 检查参数合法性 */
    if ((l_u8_recv_buf == NULL) || (l_sockaddr == NULL) || (l_u32_data_len == 0))
    {
        goto error;
    }

#if 0   // debug
    printf("net_anlysis_procotol %d Byte data: ", l_u32_data_len);
    for(uint32_t i = 0; i < l_u32_data_len; i++)
    {
        printf("0x%02x ", l_u8_recv_buf[i]);
    }
    printf("\n");
#endif 

    /* 数据校验 */
    if(bsp_crc16_xmodem_check(l_u8_recv_buf, l_u32_data_len) == 0)
    {
        printf("net frame crc 16 check error!\n");
        goto error;
    }

    /* 解析链路地址 */
    if (l_u8_recv_buf[l_u32_idx] != NET_LINK_ADDR)
    {
        printf("net frame link addr error!\n");
        goto error;
    }
    l_u32_idx += 2;

    /* 解析并且记录发送方标识 */
    memset(&g_net_recv_send_id, 0x00, sizeof(IDENTITY));
    p_id = (IDENTITY *)(&l_u8_recv_buf[l_u32_idx]);
    memcpy(g_net_recv_send_id.AreaCode, p_id->AreaCode, sizeof(g_net_recv_send_id.AreaCode));
    g_net_recv_send_id.type = p_id->type;
    g_net_recv_send_id.num = p_id->num;
#if 0   // debug
    printf("sender p_id->AreaCode %d Byte data: ", sizeof((p_id->AreaCode)));
    for(uint32_t i = 0; i < sizeof((p_id->AreaCode)); i++)
    {
        printf("0x%02x ", p_id->AreaCode[i]);
    }
    printf("\n");
#endif 
    l_u32_idx += sizeof(IDENTITY);

    /* 解析接收方标识 */
    p_id = (IDENTITY *)&l_u8_recv_buf[l_u32_idx];
#if 0   // debug
    printf("receiver p_id->AreaCode %d Byte data: ", sizeof((p_id->AreaCode)));
    for(uint32_t i = 0; i < sizeof((p_id->AreaCode)); i++)
    {
        printf("0x%02x ", p_id->AreaCode[i]);
    }
    printf("\n");
#endif 
    if ((*(uint32_t *)(p_id->AreaCode) & 0x00FFFFFF) != 0x000000) // 行政区域代码
    {
        printf("net frame receiver area code error!, p_id->AreaCode = %u\n", (*(uint32_t *)(p_id->AreaCode) & 0x00FFFFFF));
        goto error;
    }
    if (p_id->type != MMW_LIDAR)        // 标识类型
    {
        printf("net frame recver id type error, p_id->type = %u\n", p_id->type);
        goto error;
    }
    if (p_id->num != DEV_SN_NUM)
    {
        printf("net frame recver id num error, p_id->type = %u\n", p_id->num);
        goto error;
    }
    l_u32_idx += sizeof(IDENTITY);


    /* 解析协议版本 */
    l_u8protol_ver = l_u8_recv_buf[l_u32_idx++];

    /* 解析操作类型 */
    l_u8operate_type = l_u8_recv_buf[l_u32_idx++];

    /* 解析对象标识 */
    memcpy(&l_u16operate_target, &l_u8_recv_buf[l_u32_idx], sizeof(uint16_t));
    l_u32_idx += 2;

    /* 根据操作类型进行处理 */
    switch (l_u8operate_type)
    {
        case QUERY_REQUEST:
        {
            break;
        }
        case SET_REQUEST:
        {
            break;
        }
        case PROACT_UPLOAD:
        {
            break;
        }
        case QUERY_RESPONSE:
        {
            break;
        }
        case SET_RESPONSE:
        {
            break;
        }
        case PROACT_UPLOAD_RESPONSE:
        {
            break;
        }
        case ERROR_RESPONSE:
        {
            break;
        }
        case QUERY_START_REQUEST:
        {
            switch (l_u16operate_target)
            {
                case ORIGINAL_MIPI_DATA:
                {
                    if (g_mipi_data_upload_flag)   // 正在上传mipi数据时，不重复响应请求mipi数据的指令
                    {
                        printf("original mipi data is uploading, please wait.\n");
                    }
                    else
                    {
                        p_mipi_req = (ORIGNAL_MIPI_REQ *)(&l_u8_recv_buf[l_u32_idx]);
                        anlysis_origi_mipi_req(p_mipi_req);
                    }
                    break;
                }
                case DSP_OUTPUT_DATA:
                {
                    p_dsp_req = (DSP_CAL_DATA_REQ *)(&l_u8_recv_buf[l_u32_idx]);
                    anlysis_dsp_req(p_dsp_req);
                    break;
                }
                default:
                    printf("net frame QUERY_START_REQUEST operation target err, operation target is 0x%02x.\n", l_u16operate_target);
                    break;
            }
            break;
        }
        case CIRCULAR_RESPONSE_CONFIRM_INFO:
        {
            switch (l_u16operate_target)
            {
                case ORIGINAL_MIPI_DATA:
                    p_mipi_res = (ORIGNAL_MIPI_RES *)(&l_u8_recv_buf[l_u32_idx]);
                    anlysis_origi_mipi_res(p_mipi_res);
                    break;
                
                default:
                    break;
            }
            break;
        }
        default:
            printf("net frame operation type err, operation type is 0x%02x.\n", l_u8operate_type);
            break;
    }

    error:
    RETURN_ERROR_CODE(l_u32_ret, __func__);
}
/**
 * @brief 网络协议添加帧头帧尾等信息
 * 
 * @param l_u8_send_data ：待发送的数据包数组指针
 * @param l_u32_data_len ：待发送的数据内容长度（不包括帧头等附加信息）
 * @param l_u8_master_cmd ：主指令号
 * @param l_u8_subid_cmd ： 子指令号
 * 
 * @return uint32_t ：0：正常，非0：错误代码
 * 
 * @note：
 */
uint32_t wlr_add_protocol_head_tail(uint8_t *l_u8_send_data, uint32_t l_u32_data_len, uint8_t l_u8_master_cmd, uint8_t l_u8_subid_cmd)
{
    uint8_t  l_u8_check_type = TAG_BCC_CHECK;                               // 校验类型，00：不校验，01：异或，02：CRC
    uint8_t  l_u8_fram_type = 2;                                             // 帧类型，01：请求，02：应答，03：主动上报
    uint16_t l_u16_check_value = 0;                                          // 校验值
    uint16_t l_u16_fram_len = NET_SEND_FRAM_HEAD_LEN + l_u32_data_len + 4;   // 帧长：帧头 + 数据长度 + 校验 + 帧尾
    uint32_t l_u32_ret = 0;
    uint32_t l_u32_idx = 0;

    /* 帧头 */
    l_u8_send_data[l_u32_idx++] = 0x00;
    l_u8_send_data[l_u32_idx++] = 0x00;

    /* 帧长 */
    *((uint16_t *)&l_u8_send_data[l_u32_idx]) = l_u16_fram_len;
    l_u32_idx += 2;

    /* 时间戳 */
    l_u32_idx += 8;

    /* 校验类型 */
    l_u8_send_data[l_u32_idx++] = l_u8_check_type;

    /* 帧类型 */
    l_u8_send_data[l_u32_idx++] = l_u8_fram_type;

    /* 设备类型 */
    *((uint16_t *)&l_u8_send_data[l_u32_idx]) = 0x9420;
    l_u32_idx += 2;

    /* 保留 */
    l_u32_idx += 8;

    /* 主指令和子指令 */
    l_u8_send_data[l_u32_idx++] = l_u8_master_cmd;
    l_u8_send_data[l_u32_idx++] = l_u8_subid_cmd;

    /* 命令参数 */
    l_u32_idx += 2;

    /* 数据内容 */
    l_u32_idx += l_u32_data_len;

    /* 计算校验值 */
    switch (l_u8_check_type)
    {
        case TAG_NONE_CHECK:
        {
            break;
        }
        case TAG_BCC_CHECK:
        {
            l_u16_check_value = bsp_bcc_calculate(&l_u8_send_data[2], l_u32_idx - 2);
            break;
        }
        case TAG_CRC_CHECK:
        {
            l_u16_check_value = bsp_crc16_xmodem_calculate(&l_u8_send_data[2], l_u32_idx - 2);
            break;
        }
        default:
            break;
    }

    /* 校验位 */
    *((uint16_t *)&l_u8_send_data[l_u32_idx]) = l_u16_check_value;
    l_u32_idx += 2;

    /* 帧尾 */
    l_u8_send_data[l_u32_idx++] = 0x00;
    l_u8_send_data[l_u32_idx++] = 0x00;

    error:
    RETURN_ERROR_CODE(l_u32_ret, __func__);
}

/**
 * @brief 目标原始调试数据
 * 
 * @param l_sockaddr ：接收数据包ip地址
 * @param l_u8_recv_buf ：接收数组指针
 * @param l_u8_master_cmd ：主指令号
 * @param l_u8_subid_cmd ： 子指令号
 * 
 * @return uint32_t ：0：正常，非0：错误代码
 * 
 * @note：
 */
static uint32_t wlr_01_02_raw_debug_adc_data(struct sockaddr * l_sockaddr, uint8_t *l_u8_recv_buf, uint8_t l_u8_master_cmd, uint8_t l_u8_subid_cmd)
{
    uint32_t  l_u32_channel_idx = 0, l_u32_chirp_idx = 0;
    uint32_t  l_u32_channel_num = RAW_DATA_CHIRP_CHANNEL_NUM, l_u32_chirp_num = RAW_DATA_CHIRP_NUM;
    uint32_t  l_u32_each_chirp_package = 2;          // 每chirp的总包数
    uint32_t  l_u32_each_chirp_package_idx = 0;      //
    uint32_t  l_u32_adc_point_idx = 0;               // 每包数据起始点索引

    uint32_t l_u32_ret = 0;
    uint32_t l_u32_idx = 0;
    uint8_t  *l_u8_send_data = NULL;
    uint32_t l_u32_send_data_len = 1062;             // 发送的数据长度

    /* 申请互斥信号量 */
    pthread_mutex_lock(&g_net_param_semaphore);

    /* 分配发送内存 */
    l_u8_send_data = malloc(l_u32_send_data_len);
    if (l_u8_send_data == NULL)
    {
        printf("malloc send data failed!\n");
        SET_ERROR_CODE(l_u32_ret, 0);
        goto error;
    }
    
    for (l_u32_channel_idx = 0; l_u32_channel_idx < l_u32_channel_num; l_u32_channel_idx++)
    {
        for (l_u32_chirp_idx = 0; l_u32_chirp_idx < l_u32_chirp_num; l_u32_chirp_idx++)
        {
            for (l_u32_each_chirp_package_idx = 0; l_u32_each_chirp_package_idx < l_u32_each_chirp_package; l_u32_each_chirp_package_idx++)
            {
                /* 跳过帧头、帧长、校验 */
                l_u32_idx += NET_SEND_FRAM_HEAD_LEN;

                /* 添加数据内容 */
                l_u8_send_data[l_u32_idx++] = l_u32_channel_num;               // 总通道数
                l_u8_send_data[l_u32_idx++] = l_u32_channel_idx;               // 通道号
                l_u8_send_data[l_u32_idx++] = l_u32_chirp_num;                 // 总chirp数
                l_u8_send_data[l_u32_idx++] = l_u32_chirp_idx;                 // chirp序号
                l_u8_send_data[l_u32_idx++] = l_u32_each_chirp_package;        // 每个chirp总包数
                l_u8_send_data[l_u32_idx++] = l_u32_each_chirp_package_idx;    // 每个chirp包序号
                
                l_u32_adc_point_idx = l_u32_each_chirp_package_idx * 512;      // (1024 / 2)    每包数据起始点索引
                memcpy(&l_u8_send_data[l_u32_idx], &g_fram_raw_data[0].channel[l_u32_channel_idx].raw_adc_data[l_u32_chirp_idx][l_u32_adc_point_idx], 1024); // 待发送的原始数据
                l_u32_idx += 1024;

                /* 添加帧头帧尾 */
                wlr_add_protocol_head_tail(&l_u8_send_data[0], (l_u32_idx - NET_SEND_FRAM_HEAD_LEN), l_u8_master_cmd, l_u8_subid_cmd);

                /* 网络发送数据 */
                if (net_send_udp_data(&l_u8_send_data[0], (l_u32_idx + 4), l_sockaddr, SOCKET_CMD_TYPE) != 0)
                {
                    // printf("net send udp data failed!\n");
                    SET_ERROR_CODE(l_u32_ret, 1);
                    goto error;
                }
                l_u32_idx = 0;
            }
            usleep(2);  // 适当延时  
        }  
    }

    /* 释放互斥信号量 */
    pthread_mutex_unlock(&g_net_param_semaphore);

    error:
    /* 释放内存 */
    if (l_u8_send_data != NULL)
    {
        free(l_u8_send_data);
        l_u8_send_data = NULL;
    }
    RETURN_ERROR_CODE(l_u32_ret, __func__);
}


/**
 * @brief 广播设备信息
 * 
 * @param l_sockaddr ：接收数据包ip地址
 * @param l_u8_recv_buf ：接收数组指针
 * @param l_u8_master_cmd ：主指令号
 * @param l_u8_subid_cmd ： 子指令号
 * 
 * @return uint32_t ：0：正常，非0：错误代码
 * 
 * @note：
 */
static uint32_t wlr_03_04_broadcast_device_info(struct sockaddr * l_sockaddr, uint8_t *l_u8_recv_buf, uint8_t l_u8_master_cmd, uint8_t l_u8_subid_cmd)
{
    uint32_t l_u32_ret = 0;

    /* 申请互斥信号量 */
    pthread_mutex_lock(&g_net_param_semaphore);

    // test
    uint8_t l_u8_send_buf[] = {0x07, 0x01, 0x05, 0x08, 0x05, 0x06};
    net_send_udp_data(l_u8_send_buf, sizeof(l_u8_send_buf), l_sockaddr, SOCKET_BROADCAST_TYPE);

    /* 释放互斥信号量 */
    pthread_mutex_unlock(&g_net_param_semaphore);

    error:
    RETURN_ERROR_CODE(l_u32_ret, __func__);
}

/**
 * @brief 设备协议版本
 * 
 * @param l_sockaddr ：接收数据包ip地址
 * @param l_u8_recv_buf ：接收数组指针
 * @param l_u8_master_cmd ：主指令号
 * @param l_u8_subid_cmd ： 子指令号
 * 
 * @return uint32_t ：0：正常，非0：错误代码
 * 
 * @note：
 */
static uint32_t wlr_04_01_device_protocol_version(struct sockaddr * l_sockaddr, uint8_t *l_u8_recv_buf, uint8_t l_u8_master_cmd, uint8_t l_u8_subid_cmd)
{
    uint8_t  l_u8_arm_version[24] = {0};
    uint32_t l_u32_ret = 0;
    uint32_t l_u32_idx = 0;
    uint8_t  *l_u8_send_data = NULL;
    uint32_t l_u32_send_data_len = 78;                     // 发送的数据长度

    uint8_t  l_u8_sn[20] = "mmv000120241122";

    /* 申请互斥信号量 */
    pthread_mutex_lock(&g_net_param_semaphore);

    /* 分配发送内存 */
    l_u8_send_data = malloc(l_u32_send_data_len);
    if (l_u8_send_data == NULL)
    {
        printf("malloc send data failed!\n");
        SET_ERROR_CODE(l_u32_ret, 0);
        goto error;
    }
    
    /* 跳过帧头、帧长、校验 */
    l_u32_idx += NET_SEND_FRAM_HEAD_LEN;

    /* 添加数据内容 */
    memcpy(&l_u8_send_data[l_u32_idx], l_u8_sn, sizeof(l_u8_sn));
    l_u32_idx += sizeof(l_u8_sn);
    memcpy(&l_u8_send_data[l_u32_idx], ARM_VERSION, sizeof(ARM_VERSION));
    l_u32_idx += sizeof(ARM_VERSION);

    /* 添加帧头帧尾 */
    wlr_add_protocol_head_tail(&l_u8_send_data[0], (l_u32_idx - NET_SEND_FRAM_HEAD_LEN), l_u8_master_cmd, l_u8_subid_cmd);

    /* 网络发送数据 */
    if (net_send_udp_data(&l_u8_send_data[0], (l_u32_idx + 4), l_sockaddr, SOCKET_CMD_TYPE) != 0)
    {
        printf("net send udp data failed!\n");
        SET_ERROR_CODE(l_u32_ret, 1);
        goto error;
    }

    /* 释放互斥信号量 */
    pthread_mutex_unlock(&g_net_param_semaphore);

    error:
    /* 释放内存 */
    if (l_u8_send_data != NULL)
    {
        free(l_u8_send_data);
        l_u8_send_data = NULL;
    }
    RETURN_ERROR_CODE(l_u32_ret, __func__);
}

/**
 * @brief 获取dsp调试参数
 * 
 * @param l_sockaddr ：接收数据包ip地址
 * @param l_u8_recv_buf ：接收数组指针
 * @param l_u8_master_cmd ：主指令号
 * @param l_u8_subid_cmd ： 子指令号
 * 
 * @return uint32_t ：0：正常，非0：错误代码
 * 
 * @note：
 */
static uint32_t wlr_09_01_get_dsp_debug_param(struct sockaddr * l_sockaddr, uint8_t *l_u8_recv_buf, uint8_t l_u8_master_cmd, uint8_t l_u8_subid_cmd)
{
    uint8_t  l_u8_dsp_version[24] = {0};
    uint32_t l_u32_ret = 0;
    uint32_t l_u32_idx = 0;
    uint8_t  *l_u8_send_data = NULL;
    uint32_t l_u32_send_data_len = NET_SEND_FRAM_HEAD_LEN + sizeof(g_arm_debug_param) + 4;           // 发送的数据长度

    rproc_info_type *l_rproc_info = get_rpmsg_rproc_info();

    /* 申请互斥信号量 */
    pthread_mutex_lock(&g_net_param_semaphore);

    /* 分配发送内存 */
    l_u8_send_data = malloc(l_u32_send_data_len);
    if (l_u8_send_data == NULL)
    {
        printf("malloc send data failed!\n");
        SET_ERROR_CODE(l_u32_ret, 0);
        goto error;
    }
    
    /* 跳过帧头、帧长、校验 */
    l_u32_idx += NET_SEND_FRAM_HEAD_LEN;

    /* 添加数据内容 */
    memcpy(&l_u8_send_data[l_u32_idx], (uint8_t *)g_arm_debug_param, sizeof(g_arm_debug_param));
    l_u32_idx += sizeof(g_arm_debug_param);

    /* 添加帧头帧尾 */
    wlr_add_protocol_head_tail(&l_u8_send_data[0], (l_u32_idx - NET_SEND_FRAM_HEAD_LEN), l_u8_master_cmd, l_u8_subid_cmd);

    /* 网络发送数据 */
    if (net_send_udp_data(&l_u8_send_data[0], (l_u32_idx + 4), l_sockaddr, SOCKET_CMD_TYPE) != 0)
    {
        printf("net send udp data failed!\n");
        SET_ERROR_CODE(l_u32_ret, 1);
        goto error;
    }

    /* 释放互斥信号量 */
    pthread_mutex_unlock(&g_net_param_semaphore);

    error:
    /* 释放内存 */
    if (l_u8_send_data != NULL)
    {
        free(l_u8_send_data);
        l_u8_send_data = NULL;
    }
    RETURN_ERROR_CODE(l_u32_ret, __func__);
}
/**
 * @brief 设置dsp调试参数
 * 
 * @param l_sockaddr ：接收数据包ip地址
 * @param l_u8_recv_buf ：接收数组指针
 * @param l_u8_master_cmd ：主指令号
 * @param l_u8_subid_cmd ： 子指令号
 * 
 * @return uint32_t ：0：正常，非0：错误代码
 * 
 * @note：
 */
static uint32_t wlr_09_02_set_dsp_debug_param(struct sockaddr * l_sockaddr, uint8_t *l_u8_recv_buf, uint8_t l_u8_master_cmd, uint8_t l_u8_subid_cmd)
{
    uint8_t  l_u8_arm_version[24] = {0};
    uint32_t l_u32_ret = 0;
    uint32_t l_u32_idx = 0;
    uint8_t  *l_u8_send_data = NULL;
    uint32_t l_u32_send_data_len = NET_SEND_FRAM_HEAD_LEN + 4 + 4;           // 发送的数据长度

    /* 申请互斥信号量 */
    pthread_mutex_lock(&g_net_param_semaphore);

    /* 解析接收的数据 */
    memcpy((uint8_t *)g_arm_debug_param, l_u8_recv_buf, sizeof(g_arm_debug_param));

    // test
    for (uint8_t i = 0; i < (sizeof(g_arm_debug_param) / sizeof(g_arm_debug_param[0])); i++)
    {
        printf("g_arm_debug_param(%d):%d\n", i, g_arm_debug_param[i]);
    }
    //

    /* 分配发送内存 */
    l_u8_send_data = malloc(l_u32_send_data_len);
    if (l_u8_send_data == NULL)
    {
        printf("malloc send data failed!\n");
        SET_ERROR_CODE(l_u32_ret, 0);
        goto error;
    }
    
    /* 跳过帧头、帧长、校验 */
    l_u32_idx += NET_SEND_FRAM_HEAD_LEN;

    /* 添加数据内容 */
    *(uint32_t *)&l_u8_send_data[l_u32_idx] = 0x00000001;
    l_u32_idx += 4;

    /* 添加帧头帧尾 */
    wlr_add_protocol_head_tail(&l_u8_send_data[0], (l_u32_idx - NET_SEND_FRAM_HEAD_LEN), l_u8_master_cmd, l_u8_subid_cmd);

    /* 网络发送数据 */
    if (net_send_udp_data(&l_u8_send_data[0], (l_u32_idx + 4), l_sockaddr, SOCKET_CMD_TYPE) != 0)
    {
        printf("net send udp data failed!\n");
        SET_ERROR_CODE(l_u32_ret, 1);
        goto error;
    }

    /* 释放互斥信号量 */
    pthread_mutex_unlock(&g_net_param_semaphore);

    error:
    /* 释放内存 */
    if (l_u8_send_data != NULL)
    {
        free(l_u8_send_data);
        l_u8_send_data = NULL;
    }
    RETURN_ERROR_CODE(l_u32_ret, __func__);
}
